/**************************************************************************//**
 * @file           main.c
 * @version        V1.0
 * $Revision:      1 $
 * $Date:          2017/01/04 $
 * @brief          Main function
 * @Author         Jeffrey Kang
 * @ContactInfo    chkang@esmt.com.tw
 *
 * @note
 *
 * Copyright (C) 1998 Elite Semiconductor Memory Technology Corp.
 * All rights reserved.
 *
 ******************************************************************************/


#include <REG52.h>
#include "system_FE81001.h"


static volatile unsigned char xdata spi_data[5] = {0x01,0x02,0x03,0x04,0x05};
static volatile unsigned char xdata spi_read_data[5] = {0};
unsigned char int_stat; 
unsigned char int_stat_1; 
unsigned char int_stat_2; 
unsigned char cnt = 0;

/**
 * @brief       delay function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void delay (void)
{
	unsigned int i;
	
	for( i = 0 ; i < 5 ; i++ ){}
}


/**
 * @brief       SPIISR function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
const void SPIISR (void) interrupt ISR_SPI
{
	int_stat = SPI->int_stat;
	
	PD->gpio_dout1 = ~PD->gpio_dout1;
	
	if ((int_stat & 0x10) == 0x10)
		SPI->int_stat |= 0x10;
	
	/* enable global interrupt */
	INTC->int_gmask = 0x01;
}


/**
 * @brief       SPIMasterTransmitConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void SPIMasterTransmitConfig()
{
#if 0
	SPI->trans_fmt[0]    = 0x1F;       // DataMerge(1) = 0, 0, 0, MOSIBiDir(1) = 1, LSB(1) = 1, SlvMode(1) = 1, CPOL(1) = 1, CPHA(1) = 1
	SPI->trans_fmt[1]    = 0x9F;       // AddrLen(2) = 2, 0, DataLen(5) = 0x1F
	SPI->trans_ctrl[0]   = 0xFF;       // RdTranCnt(8) = 0xFF
	SPI->trans_ctrl[1]   = 0xFF;       // WrTranCnt(4) = 15, TokenValue(1) = 1, DummyCnt(2) = 0 ,RdTranCnt(1) = 1
	SPI->trans_ctrl[2]   = 0xFF;       // DualQuad(2) = 0, TokenEn(1) = 1, WrTranCnt(5) = 15
	SPI->trans_ctrl[3]   = 0x7F;       // 0, CmdEn(1) = 1, AddrEn(1) = 1, AddrFmt(1) = 0, TransMode(4) = 15
	SPI->spi_cmd         = 0x00;       //
	SPI->spi_adr[0]      = 0xFF;
	SPI->spi_adr[1]      = 0xFF;
	SPI->spi_adr[2]      = 0xFF;
	SPI->spi_dat         = 0xFF;
	SPI->spi_ctrl[0]     = 0x07;       // 0, 0, 0, TXDMAEN(1) = 0, RXDMAEN(1) = 0, TXFIFORST(1) = 1, RXFIFORST(1) = 1, SPIRST(1) = 1
	SPI->spi_ctrl[1]     = 0x1F;       // 0, 0, 0, RXTHRES(5) = 0x1F
	SPI->spi_ctrl[2]     = 0x1F;       // 0, 0, 0, TXTHRES(5) = 0x1F
	//spi_stat[0]                        // 0, 0, 0, 0, 0, 0, 0, SPIActive(1)
	//spi_stat[1]                        // RXFULL(1), RXEMPTY(1), 0, RXNUM(5)
	//spi_stat[2]                        // TXFULL(1), TXEMPTY(1), 0, TXNUM(5)
	SPI->int_en         = 0x3F;        // 0, 0, SlvCmdEn(1) = 1, EndIntEn(1) = 1, TXFIFOIntEn(1) = 1, RXFIFOIntEn(1) = 1, TXFIFOURIntEn(1) = 1, RXFIFOORIntEn(1) = 1
	//int_stat                           // 0, 0, SlvCmdEn(1), EndIntEn(1), TXFIFOIntEn(1), RXFIFOIntEn(1), TXFIFOURIntEn(1), RXFIFOORIntEn(1)
	SPI->intf_timing[0] = 0xFF;        // SCLK_DIV(8) = 0xFF
	SPI->intf_timing[1] = 0xFF;        // 0, 0, CS2SCLK(2) = 3, CSHT(4) = 15
	SPI->slv_stat[0]    = 0xFF;        // USR_Status(8)
	SPI->slv_stat[1]    = 0xFF;        // USR_Status(8)
	SPI->slv_stat[2]    = 0x01;        // 0, 0, 0, 0, 0, UnderRun(1), OverRun(1), Ready(1) = 1
	//slv_rcvcnt[0]                      // RCnt(8)
	//slv_rcvcnt[1]                      // 0, 0, 0, 0, 0, 0, 0, RCnt(1)
	//slv_tsmcnt[0]                      // WCnt(8)
	//slv_tsmcnt[1]                      // 0, 0, 0, 0, 0, 0, 0, WCnt(1)
	//SPI->spi_cfg                       // 0, 0, RxFIFOSize(2), 0, 0, RxFIFOSize(2)
#endif
	
	/* wait SPI transfer finished */
	while((SPI->spi_stat[0] & 0x01) == 0x01){}
	
	/* set SPI transfer format */
	SPI->trans_fmt[0] = 0x00;          // DataMerge(1) = 0, 0, 0, MOSIBiDir(1) = 0, LSB(1) = 0, SlvMode(1) = 0, CPOL(1) = 0, CPHA(1) = 0
	SPI->trans_fmt[1] = 0x07;          // AddrLen(2) = 1 ((addrlen(u:bytes)-1)), 0, DataLen(5) = 0x07 ((datalen(u:bits))-1)
	
	/* set SPI transfer control */
	SPI->trans_ctrl[0] = 0x00;         // RdTranCnt(8) = 0
	SPI->trans_ctrl[1] = 0x00;         // WrTranCnt(4) = 0 (1-byte data_), TokenValue(1) = 0, DummyCnt(2) = 0 ,RdTranCnt(1) = 0
	SPI->trans_ctrl[2] = 0x00;         // DualQuad(2) = 0, TokenEn(1) = 0, WrTranCnt(5) = 0
	SPI->trans_ctrl[3] = 0x01;         // 0, CmdEn(1) = 0, AddrEn(1) = 1, AddrFmt(1) = 0, TransMode(4) = 1 (write only)
	
	/* set SPI control */
	SPI->spi_ctrl[0] = 0x07;           // 0, 0, 0, TXDMAEN(1) = 0, RXDMAEN(1) = 0, TXFIFORST(1) = 1, RXFIFORST(1) = 1, SPIRST(1) = 1
	SPI->spi_ctrl[1] = 0x00;           // 0, 0, 0, RXTHRES(5) = 0x00
	SPI->spi_ctrl[2] = 0x00;           // 0, 0, 0, TXTHRES(5) = 0x00
	
	/* set interrupt enable */
	//SPI->int_en = 0x14;                // 0, 0, SlvCmdEn(1) = 0, EndIntEn(1) = 1, TXFIFOIntEn(1) = 0, RXFIFOIntEn(1) = 0, TXFIFOURIntEn(1) = 0, RXFIFOORIntEn(1) = 0
	
	/* enable global interrupt */
	//INTC->int_gmask = 0x01;
	
	/* set SPI interface timing */
	SPI_Clock_1M();
	


}

/**
 * @brief       IOConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void IOConfig()
{
	/* enable P0.0(MISO), P0.1(MOSI), P0.2 (SCLK), P0.3 (SS) function */
	Set_PA0_MISO();
	Set_PA1_MOSI();
	Set_PA2_SCLK();
	PORT_SetPAGPIO(BIT3); // PA3 as GPIO(SS)
	
	/* enable P0.0 input (MISO), P0.1 output (MOSI), P0.2 output (SCLK), P0.3 output (SS) */
	PORT_SetPAInput(BIT0);
	PORT_SetPAPushPull(BIT1 | BIT2 | BIT3);
	
	/* Set PC7 input as button */
	PORT_SetPCInput(BIT7);

	/* Set PD1. ,PD2.,PD3 output */
	PORT_SetPDPushPull(BIT1 | BIT2 | BIT3 );
	
	
 PD1 = 0; // LED_G1 On
	PD2 = 1 ; //LED_R Off
	PD3= 0;  // LED_G2  On
	
	PA3 =1; // SS
}


/**
 * @brief       CLKConfig function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
void CLKConfig()
{	
	/* enable GPIO clock */
	PORT_PAPBPCPD_Clock_Enable();	// enable GPIOA GPIOB GPIOC GPIOD clock
	
	/* enable SPI clock */
	En_SPI_clk();
	
}

void SPI_WriteByte( unsigned char data_)
{
	SPI->trans_ctrl[3] = 0x01; // Write only   
	SPI->spi_dat = data_;
	SPI->spi_cmd = 0x02;
	delay();
	while( (SPI->int_stat & 0x10) == 0x10){}
	SPI->int_stat |= 0x10;
	SPI->spi_ctrl[0] = 0x06;
}

unsigned char SPI_ReadByte( unsigned char dummy)
{
	unsigned char data_ =  0 ;
	SPI->trans_ctrl[3] = 0x02; // Read only   
	SPI->spi_dat = dummy;
	SPI->spi_cmd = 0x03;
	delay();
	while( (SPI->int_stat & 0x10) == 0x10){}
	SPI->int_stat |= 0x10;
	data_ =  SPI->spi_dat ;
	SPI->spi_ctrl[0] = 0x06;
		
	return data_;
}



/**
 * @brief       main function
 *
 * @param       None
 *
 * @return      None
 *
 * @details     1. 
 */
int main (void)
{
	CLKConfig();
	IOConfig();
	
	SPIMasterTransmitConfig();

	delay();
	
	while(1)
	{
			if( Get_PCx_input(7) == 0)   // PC7  = 0 , button down
			{
						while(Get_PCx_input(7) == 0){}
							
						PD2 = 0 ; //LED_R On
				
						// SPI Write and Read
							
						PA3 = 0; // Pull low PA3(SS)
	
						SPI_WriteByte(0x90); //Write 0x90
						SPI_WriteByte(0x00); //Write 0x00
						SPI_WriteByte(0x00); //Write 0x00
						SPI_WriteByte(0x00); //Write0x00
							
						spi_read_data[0] = SPI_ReadByte(0x11); //Read  (0x11 is Dummy Write)	
						spi_read_data[1] = SPI_ReadByte(0x11); //Read  (0x11 is Dummy Write)
						
						PA3=1;// Pull high PA3(SS)
				
			}
			else
			{
					PD2 = 1 ; //LED_R Off
			}
	}
}

